package com.eleventwelve.iris.web.controller;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.opentides.bean.SystemCodes;
import org.opentides.editor.BaseEntityEditor;
import org.opentides.service.SystemCodesService;
import org.opentides.util.StringUtil;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

import com.eleventwelve.iris.entity.MedicalProcedure;
import com.eleventwelve.iris.entity.MedicalProgramTreatment;
import com.eleventwelve.iris.entity.Medicine;
import com.eleventwelve.iris.entity.PatientMedicalProgram;
import com.eleventwelve.iris.entity.PrescribedMedicine;
import com.eleventwelve.iris.entity.Prescription;
import com.eleventwelve.iris.entity.Staff;
import com.eleventwelve.iris.service.MedicalProcedureService;
import com.eleventwelve.iris.service.MedicalProgramTreatmentService;
import com.eleventwelve.iris.service.MedicineService;
import com.eleventwelve.iris.service.PatientMedicalProgramService;
import com.eleventwelve.iris.service.PrescribedMedicineService;
import com.eleventwelve.iris.service.PrescriptionService;
import com.eleventwelve.iris.service.StaffService;

@SuppressWarnings("deprecation")
public class ProgramTreatmentFormController extends SimpleFormController{
	private StaffService staffService;
	private MedicalProgramTreatmentService medicalProgramTreatmentService;
	private SystemCodesService systemCodesService;
	private MedicalProcedureService medicalProcedureService;
	private MedicineService medicineService;
	private PrescribedMedicineService prescribedMedicineService;
	private PatientMedicalProgramService patientMedicalProgramService;
	private PrescriptionService prescriptionService;
	
	@Override
	protected Object formBackingObject(HttpServletRequest request)
			throws Exception {
		MedicalProgramTreatment medicalProgramTreatment = new MedicalProgramTreatment();
		
		String action = request.getParameter("action");
		if(action.equalsIgnoreCase("update")){
			String id = request.getParameter("id");
			if(!StringUtil.isEmpty(id) && StringUtils.isNumeric(id)){
				medicalProgramTreatment = medicalProgramTreatmentService.load(id);
			}
		} else {	//create
			String programId = request.getParameter("programId");
			if(!StringUtil.isEmpty(programId) && StringUtils.isNumeric(programId)){
				PatientMedicalProgram program = patientMedicalProgramService.load(programId);
				medicalProgramTreatment.setPatientMedicalProgram(program);
			}
		}
		
		return medicalProgramTreatment;
	}
	
	@Override
	protected Map<String, Object> referenceData(HttpServletRequest request) throws Exception {
		// TODO Auto-generated method stub
		Map<String, Object> map = new HashMap<String, Object>();
		
		map.put("staffs", staffService.findAll());
		map.put("resultStatuses", systemCodesService.findSystemCodesByCategory("RESULT_STATUS"));
		map.put("procedures", medicalProcedureService.findAll());
		map.put("medicines", medicineService.findAll());
		
		return map;
	}
	
	@Override
	protected void initBinder(HttpServletRequest request,
			ServletRequestDataBinder binder) throws Exception {
		
		binder.registerCustomEditor(Staff.class, new BaseEntityEditor(staffService));
		binder.registerCustomEditor(SystemCodes.class, new BaseEntityEditor(systemCodesService));
		binder.registerCustomEditor(MedicalProcedure.class, new BaseEntityEditor(medicalProcedureService));
		binder.registerCustomEditor(Medicine.class, new BaseEntityEditor(medicineService));
		binder.registerCustomEditor(PrescribedMedicine.class, new BaseEntityEditor(prescribedMedicineService));
	}
	
	@Override
	protected ModelAndView onSubmit(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException errors) throws Exception {
		
		MedicalProgramTreatment treatment = (MedicalProgramTreatment) command;
		if(treatment.getIsCompleted()){
			Date date = new SimpleDateFormat("MM/dd/yyyy").parse(treatment.getTransientDate());
			treatment.setTreatmentDate(date);
		}
		
		Prescription prescription = treatment.getPrescription();
		
		List<PrescribedMedicine> toDelete = new ArrayList<PrescribedMedicine>();
		if(prescription.getPrescribedMedicines()!= null && prescription.getPrescribedMedicines().size()>0){	
			List<PrescribedMedicine> prescribedMedicines = prescription.getPrescribedMedicines();
			for (PrescribedMedicine prescribedMedicine : prescribedMedicines) {
				if(!prescribedMedicine.getIsDeleted() && prescribedMedicine.getMedicine()!=null){
					prescribedMedicine.setPrescription(prescription);
				} else {
					toDelete.add(prescribedMedicine);
				}
			}
			
			prescribedMedicines.removeAll(toDelete);
			for (PrescribedMedicine prescribedMedicine : toDelete) {
				if(prescribedMedicine.getId()!=null){
					prescribedMedicineService.delete(prescribedMedicine.getId());
				}
				
			}
			
			medicalProgramTreatmentService.save(treatment);
			prescriptionService.save(prescription);
		}
		
		String action = request.getParameter("action");
		
		if(action.equalsIgnoreCase("create")){
			return new ModelAndView("redirect:/patient-program.jspx?id="+treatment.getPatientMedicalProgram().getId()+"&item=treatment");
		}
		
		return new ModelAndView("redirect:/program-treatment.jspx?id="+treatment.getId()+"&action=update");
		
	}

	public StaffService getStaffService() {
		return staffService;
	}

	public void setStaffService(StaffService staffService) {
		this.staffService = staffService;
	}

	public MedicalProgramTreatmentService getMedicalProgramTreatmentService() {
		return medicalProgramTreatmentService;
	}

	public void setMedicalProgramTreatmentService(
			MedicalProgramTreatmentService medicalProgramTreatmentService) {
		this.medicalProgramTreatmentService = medicalProgramTreatmentService;
	}

	public SystemCodesService getSystemCodesService() {
		return systemCodesService;
	}

	public void setSystemCodesService(SystemCodesService systemCodesService) {
		this.systemCodesService = systemCodesService;
	}

	public MedicalProcedureService getMedicalProcedureService() {
		return medicalProcedureService;
	}

	public void setMedicalProcedureService(MedicalProcedureService medicalProcedureService) {
		this.medicalProcedureService = medicalProcedureService;
	}

	public MedicineService getMedicineService() {
		return medicineService;
	}

	public void setMedicineService(MedicineService medicineService) {
		this.medicineService = medicineService;
	}

	public PrescribedMedicineService getPrescribedMedicineService() {
		return prescribedMedicineService;
	}

	public void setPrescribedMedicineService(PrescribedMedicineService prescribedMedicineService) {
		this.prescribedMedicineService = prescribedMedicineService;
	}

	public PatientMedicalProgramService getPatientMedicalProgramService() {
		return patientMedicalProgramService;
	}

	public void setPatientMedicalProgramService(
			PatientMedicalProgramService patientMedicalProgramService) {
		this.patientMedicalProgramService = patientMedicalProgramService;
	}

	public PrescriptionService getPrescriptionService() {
		return prescriptionService;
	}

	public void setPrescriptionService(PrescriptionService prescriptionService) {
		this.prescriptionService = prescriptionService;
	}
	
}
